package com.siyoumi.app.modules.sheet.service;

import com.siyoumi.app.entity.SysSheet;
import com.siyoumi.app.entity.SysSheetRecord;
import com.siyoumi.app.entity.SysUser;
import com.siyoumi.app.entity.WxUser;
import com.siyoumi.app.modules.sheet.entity.SysSheetItem;
import com.siyoumi.app.modules.sheet.vo.SysSheetSaveData;
import com.siyoumi.app.service.SysSheetRecordService;
import com.siyoumi.app.service.SysSheetService;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.LinkedMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class SvcSheet
        implements IWebService {
    static public SvcSheet getBean() {
        return XSpringContext.getBean(SvcSheet.class);
    }

    static public SysSheetService getApp() {
        return SysSheetService.getBean();
    }


    /**
     * 子项
     *
     * @param sheetId
     */
    public List<SysSheetItem> getItems(String sheetId) {
        List<SysSheetItem> list = new ArrayList<>();
        SysSheet entitySheet = getApp().getEntity(sheetId);
        if (XStr.isNullOrEmpty(entitySheet.getSheet_item_data())) {
            return list;
        }

        list = XJson.parseArray(entitySheet.getSheet_item_data(), SysSheetItem.class);
        return list;
    }

    /**
     * 可用的字段
     */
    public Map<String, Integer> mapField() {
        LinkedMap<String, Integer> mapField = new LinkedMap<>();
        mapField.put("scord_str_00", 1);
        mapField.put("scord_str_01", 1);
        mapField.put("scord_str_02", 1);
        mapField.put("scord_str_03", 1);
        mapField.put("scord_str_04", 1);
        mapField.put("scord_str_05", 1);
        mapField.put("scord_txt_00", 1);
        mapField.put("scord_txt_01", 1);
        mapField.put("scord_txt_02", 1);
        mapField.put("scord_txt_03", 1);

        return mapField;
    }

    /**
     * 未使用的字段
     *
     * @param items
     */
    public Map<String, Integer> mapFieldUnUse(List<SysSheetItem> items) {
        Map<String, Integer> mapField = mapField();
        for (SysSheetItem item : items) {
            mapField.remove(item.getField_key());
        }

        return mapField;
    }


    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<SysSheet> listQuery(InputData inputData) {
        String name = inputData.input("name");

        JoinWrapperPlus<SysSheet> query = SvcSheet.getApp().join();

        query.eq("sheet_x_id", XHttpContext.getX())
                .orderByDesc("sheet_create_date");
        if (XStr.hasAnyText(name)) { // 名称
            query.like("sheet_name", name);
        }

        return query;
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<SysSheetRecord> listQueryRecord(InputData inputData) {
        String userName = inputData.input("user_name");
        String uid = inputData.input("uid");
        String sheetId = inputData.input("sheet_id");

        JoinWrapperPlus<SysSheetRecord> query = SysSheetRecordService.getBean().join();
        query.join(SysUser.table(), "user_id", "scord_uid");

        query.eq("scord_x_id", XHttpContext.getX())
                .eq("user_x_id", XHttpContext.getX())
                .orderByDesc("scord_create_date");
        if (XStr.hasAnyText(sheetId)) { // 表单ID
            query.eq("scord_sheet_id", sheetId);
        }
        if (XStr.hasAnyText(userName)) { // 用户名
            query.like("user_name", userName);
        }
        if (XStr.hasAnyText(uid)) { // uid
            query.eq("scord_uid", uid);
        }

        return query;
    }

    public JoinWrapperPlus<SysSheetRecord> listQueryRecord(String sheetId, String openid) {
        InputData inputData = InputData.getIns();
        inputData.input("sheet_id", sheetId);
        inputData.input("openid", openid);
        return listQueryRecord(inputData);
    }


    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        InputData inputData = InputData.getIns();
        JoinWrapperPlus<SysSheet> query = listQuery(inputData);
        query.in("sheet_id", ids);

        List<SysSheet> list = getApp().get(query);
        for (SysSheet entity : list) {
            getApp().removeById(entity.getKey());
        }

        return r;
    }


    /**
     * 能否提交
     *
     * @param sheetId
     */
    public XReturn saveRecordCan(String sheetId) {
        SysSheet entitySheet = SvcSheet.getApp().getEntity(sheetId);
        if (entitySheet == null) {
            return EnumSys.ERR_VAL.getR("sheet_id异常");
        }

        XReturn r = entitySheet.validDate();
        if (r.err()) {
            return r;
        }

        if (entitySheet.getSheet_submit_type() == 0) {
            log.info("只能提交1次");
            JoinWrapperPlus<SysSheetRecord> queryRecord = listQueryRecord(entitySheet.getKey(), getOpenid());
            SysSheetRecord entitySheetRecord = SysSheetRecordService.getBean().first(queryRecord);
            if (entitySheetRecord != null) {
                return XReturn.getR(20045, "只能提交1次");
            }
        }

        return EnumSys.OK.getR();
    }

    /**
     * 保存表单
     *
     * @param vo
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn saveRecord(SysSheetSaveData vo) {
        XReturn r = saveRecordCan(vo.getSheet_id());
        if (r.err()) {
            return r;
        }

        SysSheet entitySheet = SvcSheet.getApp().getEntity(vo.getSheet_id());

        SvcSheet appSheet = SvcSheet.getBean();
        List<SysSheetItem> items = appSheet.getItems(entitySheet.getKey());
        log.info("检查内容");
        for (SysSheetItem item : items) {
            String val = vo.getJson().get(item.getField_key());
            if (val == null) {
                return XReturn.getR(20178, item.getLabel() + "参数缺少");
            }
            r = itemCheck(item, val);
            if (r.err()) {
                return r;
            }
        }

        // 提交key
        String key = XStr.concat(getOpenid(), "|", XDate.toDateTimeString());
        // 开始保存
        SysSheetRecord entityRecord = new SysSheetRecord();
        for (SysSheetItem item : items) {
            //赋值内容
            String val = vo.getJson().get(item.getField_key());
            entityRecord.setAttributeVal(item.getField_key(), val);
        }
        entityRecord.setScord_x_id(entitySheet.getSheet_x_id());
        entityRecord.setScord_sheet_id(entitySheet.getSheet_id());
        entityRecord.setScord_key(key);
        entityRecord.setScord_uid(getUid());
        entityRecord.setAutoID();
        SysSheetRecordService.getBean().save(entityRecord);

        r = XReturn.getR(0);
        r.setData("entity", entityRecord);

        return r;
    }


    private XReturn itemCheck(SysSheetItem item, String val) {
        log.info(XStr.concat(item.getField_key(), "[", item.getLabel(), "]"));
        if (val == null) {
            val = "";
        }

        log.info("检查字段长度");
        Integer lenMax = 200;
        if (XStr.startsWith(item.getField_key(), "scord_txt_")) {
            lenMax = 2000;
        }
        if (val.length() > lenMax) {
            return XReturn.getR(20219, item.getLabel() + "内容最大长度为：" + lenMax);
        }

        log.info("检查必填");
        if (item.getRequired() == 1) {
            if (XStr.isNullOrEmpty(val)) {
                return XReturn.getR(20219, item.getLabel() + "必填");
            }
        }

        return XReturn.getR(0);
    }

}
